package top.lixunda.ecommerce.server.user.api.entity.vo;

import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.springframework.beans.BeanUtils;
import top.lixunda.common.utils.ObjectValidators;
import top.lixunda.ecommerce.server.user.api.entity.db.SystemMenuDO;
import top.lixunda.ecommerce.server.user.api.entity.db.UserMenuDO;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 系统菜单目录表 树形结构VO
 *
 * @author lixunda
 * @version time:2020/4/23 17:17
 */
@SuppressWarnings({"Duplicates", "unused"})
@ApiModel("系统菜单目录表 树形结构VO")
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
public class SystemMenuTreeVO extends SystemMenuVO {

    /**
     * 菜单子目录
     */
    @ApiModelProperty("菜单子目录")
    private List<SystemMenuTreeVO> list;

    /**
     * 数据转换
     *
     * @param systemMenuDO SystemMenuDO
     * @return SystemMenuTreeVO
     */
    @ApiModelProperty(hidden = true)
    @JsonIgnore
    public static SystemMenuTreeVO fromSystemMenuDO(SystemMenuDO systemMenuDO) {
        if (ObjectValidators.isEmpty(systemMenuDO)) {
            return null;
        }
        SystemMenuTreeVO result = new SystemMenuTreeVO();
        BeanUtils.copyProperties(systemMenuDO, result);
        result.setList(Collections.emptyList());
        return result;
    }

    /**
     * 数据转换
     *
     * @param userMenuDO UserMenuDO
     * @return SystemMenuTreeVO
     */
    @ApiModelProperty(hidden = true)
    @JsonIgnore
    public static SystemMenuTreeVO fromUserMenuDO(UserMenuDO userMenuDO) {
        if (ObjectValidators.isEmpty(userMenuDO)) {
            return null;
        }
        SystemMenuTreeVO result = new SystemMenuTreeVO();
        BeanUtils.copyProperties(userMenuDO, result);
        result.setList(Collections.emptyList());
        return result;
    }

    /**
     * 数据转换
     *
     * @param list SystemMenuDO列表
     * @return SystemMenuTreeVO列表
     */
    @ApiModelProperty(hidden = true)
    @JsonIgnore
    public static List<SystemMenuTreeVO> fromSystemMenuList(List<SystemMenuDO> list) {
        if (list == null) {
            return null;
        }
        return list.stream()
                .map(SystemMenuTreeVO::fromSystemMenuDO)
                .collect(Collectors.toList());
    }

    /**
     * 数据转换
     *
     * @param list SystemMenuDO列表
     * @return SystemMenuTreeVO列表，数形结构
     */
    @ApiModelProperty(hidden = true)
    @JsonIgnore
    public static List<SystemMenuTreeVO> fromSystemMenuToTree(List<SystemMenuDO> list) {
        if (ObjectValidators.isEmpty(list)) {
            return null;
        }
        List<SystemMenuTreeVO> voList = list.stream()
                .map(SystemMenuTreeVO::fromSystemMenuDO)
                .filter(Objects::nonNull)
                .peek(item -> {
                    if (ObjectValidators.isEmpty(item.getParentMenuId()) || item.getParentMenuId() <= 0) {
                        item.setParentMenuId(-1);
                    }
                })
                .collect(Collectors.toList());

        Map<Integer, List<SystemMenuTreeVO>> map = voList.stream().collect(
                Collectors.toMap(SystemMenuVO::getParentMenuId, Arrays::asList,
                        (temp1, temp2) -> {
                            temp1.addAll(temp2);
                            return temp1;
                        }));

        voList.forEach(item -> {
            List<SystemMenuTreeVO> temp = map.get(item.getMenuId());
            if (ObjectValidators.isNotEmpty(temp)) {
                item.setList(temp);
            }
        });
        List<SystemMenuTreeVO> result = map.get(-1);
        return ObjectValidators.isEmpty(result) ? Collections.emptyList() : result;
    }

    /**
     * 数据转换
     *
     * @param list UserMenuDO列表
     * @return SystemMenuTreeVO列表，数形结构
     */
    @ApiModelProperty(hidden = true)
    @JsonIgnore
    public static List<SystemMenuTreeVO> fromUserMenuToTree(List<UserMenuDO> list) {
        if (ObjectValidators.isEmpty(list)) {
            return null;
        }
        List<SystemMenuTreeVO> voList = list.stream()
                .map(SystemMenuTreeVO::fromUserMenuDO)
                .filter(Objects::nonNull)
                .peek(item -> {
                    if (ObjectValidators.isEmpty(item.getParentMenuId()) || item.getParentMenuId() <= 0) {
                        item.setParentMenuId(-1);
                    }
                })
                .collect(Collectors.toList());

        Map<Integer, List<SystemMenuTreeVO>> map = voList.stream().collect(
                Collectors.toMap(SystemMenuVO::getParentMenuId, Arrays::asList,
                        (temp1, temp2) -> {
                            temp1.addAll(temp2);
                            return temp1;
                        }));

        voList.forEach(item -> {
            List<SystemMenuTreeVO> temp = map.get(item.getMenuId());
            if (ObjectValidators.isNotEmpty(temp)) {
                item.setList(temp);
            }
        });
        List<SystemMenuTreeVO> result = map.get(-1);
        return ObjectValidators.isEmpty(result) ? Collections.emptyList() : result;
    }

}
